package vip.zhenzicheng.test.juc.atomic;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * 原子更新字段demo，仅限字段属性是 public volatile int
 *
 * @author zhenzicheng
 * @date 2022-09-07 08:58
 */
@Slf4j
public class AtomicIntegerFieldUpdaterCase {

  public static void main(String[] args) throws InterruptedException {
    BankAccount bankAccount = new BankAccount();
    CountDownLatch countDownLatch = new CountDownLatch(10);

    for (int i = 0; i < 10; i++) {
      new Thread(() -> {
        try {
          for (int j = 0; j < 1000; j++) {
            // bankAccount.add();
            bankAccount.transMoney(bankAccount);
          }
        } finally {
          countDownLatch.countDown();
        }
      }, String.valueOf(i)).start();
    }
    countDownLatch.await();
    log.info("money: {}", bankAccount.money);
  }
}

class BankAccount {

  /**
   * 原子更新money
   */
  static final AtomicIntegerFieldUpdater<BankAccount> fieldUpdater = AtomicIntegerFieldUpdater.newUpdater(BankAccount.class,
    "money");
  // 要求1：使用 public volatile
  public volatile int money = 0;
  String bankName = "CCB";

  /**
   * 使用原生加锁实现原子操作
   */
  public synchronized void add() {
    money++;
  }

  /**
   * 使用原子字段更新类不加锁实现原子性操作
   */
  public void transMoney(BankAccount bankAccount) {
    fieldUpdater.getAndIncrement(bankAccount);
  }
}

